package internal

import (
	"GameServer/Common/utils"
	"GameServer/Game/dbmodule"
	"GameServer/Game/lib"
	"GameServer/Game/m"
	"fmt"
	"sort"

	log "github.com/sirupsen/logrus"
)

// 团队：每个小组 称为一个团队
type MCTeam struct {
	GroupIds []int64     // 多个小组
	LBoss    []*m.MCBoss //boss的tid和hp
	Activ    *m.MCActiv  // 记录活动
}

// 每组人数控制
const EACH_GROUP int = 50

// 团队：创建
func NewMCTeam() *MCTeam {
	return &MCTeam{}
}

// 团队：初始化团队
func (this *MCTeam) Init() {
	// 加载Boss，获取配置表信息
	_, actConfig, err := lib.GetCurrentMulCombatConfig()
	if err != nil {
		return
	}
	//有活动
	activId := int64(actConfig.ActivId)

	activ := m.GetMCActiv(1)
	if activId != activ.ActivityId { // 如果启动程序，数据库的世界Boss活动ID和配表ID，不一样了，需要重新加载活动
		this.CheckActiv() //重新检测活动，重新分组
		return
	}

	// 加载团队
	lgroup := make([]*m.MCGroup, 0)
	err = dbmodule.MgoDB.GameDB.FindAll("MCGroup", nil, nil, &lgroup)
	if err != nil || len(lgroup) == 0 {
		this.CheckActiv() //重新检测活动，重新分组
		return
	}

	this.GroupIds = make([]int64, 0)
	for _, val := range lgroup {
		this.GroupIds = append(this.GroupIds, val.Uid)
	}

	activ.Update(activ)
	this.Activ = activ
}

func (this *MCTeam) Run(closeSig chan bool) {

}

func (this *MCTeam) Destroy() {

}

// 检测活动信息
func (this *MCTeam) CheckActiv() {
	// 获取当前排名活动Id
	// 加载Boss，获取配置表信息
	wActconfig, actConfig, err := lib.GetCurrentMulCombatConfig()
	if err != nil { //没有活动
		this.RemoveActActivity() // 清除活动
		return
	}

	beginTime, _ := utils.LayoutToTime(actConfig.BeginTime)
	endTime, _ := utils.LayoutToTime(actConfig.EndTime)

	// 当前时间
	nowTime := utils.TNow()
	// 当前时间大于活动结束时间，活动结束，或者无效活动。
	if endTime.Unix() < nowTime.Unix() {
		this.RemoveActActivity() // 清除活动
		return
	}

	// 活动正在进行中
	// 当前时间小于活动时间，将活动加载到缓存中
	activId := int64(actConfig.ActivId)

	// 该活动已经启动了。
	if this.Activ != nil && activId == this.Activ.ActivityId {
		log.WithFields(log.Fields{
			"method": "CheckActiv",
		}).Error("加载活动失败：没有活动，或者活动已经启动了。")
		return
	}
	activ := &m.MCActiv{
		Uid:          1,
		ActivityId:   activId,
		RankRewardId: int64(wActconfig.RankRewardId),
		BeginTime:    beginTime.Unix(),
		EndTime:      endTime.Unix(),
	}
	activ.Update(activ)
	this.Activ = activ
	// 分组
	this.DivMCGroup()
}

// 团队：重新分组
func (this *MCTeam) DivMCGroup() {
	// 获取当前活动Id
	// 加载Boss，获取配置表信息
	wActconfig, _, err := lib.GetCurrentMulCombatConfig()
	if err != nil {
		fmt.Println(err)
		return
	}
	this.LBoss = make([]*m.MCBoss, 0)
	// Boss列表tid
	for _, item := range wActconfig.BossLst {
		// 获取boss信息
		mouster, err := lib.GetCardMonster(int64(item))
		if err != nil {
			fmt.Println(err)
			continue
		}
		// 获取怪的血量
		this.LBoss = append(this.LBoss, &m.MCBoss{
			Tid: mouster.Tid,
			Hp:  mouster.Hp,
		})
	}

	allUser := make([]*m.User, 0)
	// 从数据库获取所有玩家信息
	err = dbmodule.MgoDB.GameDB.FindAll("user", nil, nil, &allUser)
	if err != nil {
		// 获取玩家信息失败
		return
	}
	// 对玩家进行排序
	sort.Slice(allUser, func(i, j int) bool {
		if allUser[i].SlotLv == allUser[j].SlotLv {
			return allUser[i].LastLoginTime > allUser[j].LastLoginTime
		}
		return allUser[i].SlotLv > allUser[j].SlotLv
	})

	// 创建Boss战的玩家信息
	allGamer := make([]*m.MCGamer, 0)
	// 所有玩家转换信息
	for _, item := range allUser {
		gamer := m.InitMCGamer(item)

		allGamer = append(allGamer, gamer)
		gamer.Update(gamer) // 记录玩家信息
	}

	// 将整组信息存入数据库，每组信息是一条数据。
	// 开始分组
	length := len(allGamer)
	// 计算补充机器人的数量
	numRobot := EACH_GROUP - length%EACH_GROUP
	for i := 0; i < numRobot; i++ {
		allGamer = append(allGamer, m.NewMCGamerRobot())
	}
	// 重新计算数量，能被整除
	length = len(allGamer)
	num := length / EACH_GROUP // 刚好EACH_GROUP人，有num组
	var groupId int64 = 0      // 组ID，从1开始。
	this.GroupIds = make([]int64, 0)
	// 每组能分配EACH_GROUP人，进行信息初始化。
	for i := 0; i < num; i++ {
		groupId++
		group := m.InitMCGroup(groupId)

		for j := i * EACH_GROUP; j < (i+1)*EACH_GROUP; j++ {
			allGamer[j].GroupTid = groupId          //这个成员赋值组id
			allGamer[j].BossTid = this.LBoss[0].Tid //从第一个boss开始打
			allGamer[j].Update(allGamer[j])         // 记录玩家信息
		}
		group.AddMCGamers(allGamer[i*EACH_GROUP : (i+1)*EACH_GROUP]) // 添加EACH_GROUP人
		group.ReSort()                                               // 对EACH_GROUP人排序
		group.AddMCBossList(this.LBoss)                              // 每组添加boss
		group.Update(group)                                          // 将分组信息放入缓存，并存入数据库
		this.GroupIds = append(this.GroupIds, groupId)
	}
}

// 清除和移除活动
func (this *MCTeam) RemoveActActivity() {
	activ := &m.MCActiv{Uid: 1}
	activ.Update(activ)
	this.Activ = activ
}

// 分发排名奖励
func (this *MCTeam) DispatchRankReward(SendMailFunc func(uid string, title string, content string, resGoods []*m.Goods)) {
	if this.Activ == nil || this.Activ.ActivityId == 0 || utils.TNow().Unix() < this.Activ.EndTime {
		log.WithFields(log.Fields{
			"method": "MCTeam.DispatchReward",
		}).Error("boss活动不存在、活动未开始、活动未结束。")
		return
	}

	// 排名奖励表
	rewardList, err := lib.GetActRankRewardList(this.Activ.RankRewardId)
	if err != nil {
		log.WithFields(log.Fields{
			"method":   "GiveActRankReward",
			"rewardId": this.Activ.RankRewardId,
		}).Error("没有找到世界boss排名奖励")
		return
	}

	for _, item := range this.GroupIds {
		group := m.GetMCGroup(item)
		group.ReSort() // 重新排序
		// 遍历玩家，发放奖励
		for _, gamer := range group.LGamer {
			if gamer.IsRobot == 0 || gamer.Hurt < 10000 { // 是机器人 伤害小于10000 不发奖励
				continue
			}
			reward, find := rewardList[gamer.RankId]
			if find {
				var mailTitle string = "Hero Trial ranking Award"
				var mailContent string = fmt.Sprintf("Your rank is: %d", gamer.RankId)
				resGoods := make([]*m.Goods, 0)
				if reward.Rewards != nil && len(reward.Rewards) > 0 {
					for _, item := range reward.Rewards {
						resGoods = append(resGoods, &m.Goods{
							Tid: int64(item.Key),
							Num: int64(item.Value),
						})
					}
				}
				SendMailFunc(gamer.Uid.Hex(), mailTitle, mailContent, resGoods)
			}
		}
	}
}
